/*******************************************************************************
 * Copyright (c) 2010 Mikhail Garber.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License (LGPL)
 * which accompanies this distribution
 * 
 * Contributors:
 *     Mikhail Garber - initial API and implementation
 ******************************************************************************/
package plumber.model;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;


import org.apache.commons.lang.builder.ReflectionToStringBuilder;

import plumber.common.Utils;
import plumber.common.WithId;

/**
 * represents one Step in a Flow.
 * FlowStep has:
 *  name of the component and a method name to execute as part of this Step;
 * Step configuration: maximum runtime for a Step in seconds
 * and maximum retry count;
 * Set of Outcomes: those will be matched against the return value of this Step execution
 *  
 * @author mgarber
 *
 */
@SuppressWarnings("serial")
public final class FlowStep extends WithId {
	
	private String component;
	private String method;
	private int maxTimeSeconds = 5;
	private int maxRetryCount = 5;
	private Set<StepOutcome> outcomes;

	public int getMaxRetryCount() {
		return maxRetryCount;
	}

	public void setMaxRetryCount(int maxRetryCount) {
		this.maxRetryCount = maxRetryCount;
	}

	public String getComponent() {
		return component;
	}

	public void setComponent(String component) {
		this.component = component;
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	

	public Set<StepOutcome> getOutcomes() {
		if(outcomes == null) {
			return new HashSet<StepOutcome>();
		}
		return Collections.unmodifiableSet(outcomes);
	}

	public void setOutcomes(Set<StepOutcome> outcomes) {
		this.outcomes = new HashSet<StepOutcome>(outcomes);
	}

	/**
	 * validate that:
	 * component and method names are present;
	 * there is a set of Outcomes that pass their own validation
	 */
	public void validate() {
		Utils.validatePresent(component, "component");
		Utils.validatePresent(method, "method");
		if (outcomes != null) {
//			Utils.validatePresentCollection(outcomes, "outcomes");
			for (StepOutcome outcome : this.outcomes) {
				outcome.validate();
			}
		}

	}

	@Override
	public String toString() {
		
		return ReflectionToStringBuilder.toString(this);
	}

	public int getMaxTimeSeconds() {
		return maxTimeSeconds;
	}

	public void setMaxTimeSeconds(int maxTimeSeconds) {
		this.maxTimeSeconds = maxTimeSeconds;
	}

	
}
